package org.lee.cr;

/**
 * Account
 * 用一把锁有个问题，就是性能太差，会导致取款、查看余额、修改密码、查看密码这四个操作都是串行的。
 * 而用两把锁，取款和修改密码是可以并行的。用不同的锁对受保护资源进行精细化管理，能够提升性能。
 * 这种锁还有个名字，叫细粒度锁
 *
 * @author dralee
 * @date 2022-01-13 10:42:17
 **/
public class Account {
    // 锁，保护账户余额
    private final Object balLock = new Object();
    // 锁，保护账户密码
    private final Object pwdLock = new Object();
    private Integer balance;
    private String password;

    public Account(Integer balance, String password) {
        this.balance = balance;
        this.password = password;
    }

    /**
     * 取款
     *
     * @param amount
     */
    public void withDraw(Integer amount) {
        synchronized (balLock) {
            if (balance > amount) {
                this.balance -= amount;
            }
        }
    }

    /**
     * 修改密码
     *
     * @param password
     */
    public void changePassword(String password) {
        synchronized (pwdLock) {
            this.password = password;
        }
    }

    /**
     * 查看余额
     *
     * @return
     */
    public Integer getBalance() {
        synchronized (balLock) {
            return balance;
        }
    }

    /**
     * 查看密码
     *
     * @return
     */
    public String getPassword() {
        synchronized (pwdLock) {
            return password;
        }
    }

    @Override
    public String toString() {
        return "Account{" +
                "balLock=" + balLock +
                ", pwdLock=" + pwdLock +
                ", balance=" + balance +
                ", password='" + password + '\'' +
                '}';
    }
}
